#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "debug.h"
#include "interrupt.h"
#include "sysctl.h"
#include "timer.h"
#include "adc.h"
#include "gpio.h"
#include "uart.h"
#include "osram96x16x1.h"
#include <stdlib.h>


unsigned long g_ulFlags;
unsigned long value, Flchange;
int per=1, i=0;
unsigned long status=0;
char points;
char ADCval[2];
char temp[]="Speed=0\r";
//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif


void
Timer0IntHandler(void)
{
    //
    // Clear the timer interrupt.
    //
    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

    //
    // Toggle the flag for the first timer.
    //
    HWREGBITW(&g_ulFlags, 0) ^= 1;

    //
    // Update the interrupt status on the display.
    //

}

void IntToChar(unsigned long value)
{
    char num[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

    per = (value*100)/1023;
    ADCval[0] = num[per/10];
    ADCval[1] = '\0';
	OSRAM96x16x1StringDraw(ADCval, 7, 0);
	
}


void ADCIntHandler(void)
{
	 
     unsigned long ulData;
    // Clear the ADC interrupt.
    ADCIntClear(ADC_BASE, 0);
    // Read the data from the ADC.
    ADCSequenceDataGet(ADC_BASE, 0, &ulData);
	//if(ulData>0 || ulData<1023)
    if(ulData-30>value || ulData+30<value)
    {
       value=ulData;
       Flchange=1;
	   IntToChar(value);
    }
}


void
UARTSend(const unsigned char *pucBuffer, unsigned long ulCount)
{
    while(ulCount--)
    {
        // Write the next character to the UART.
        UARTCharPutNonBlocking(UART0_BASE, *pucBuffer++);
    }
}




int
main(void)
{
    unsigned long base;
	
    
	unsigned long base1;
    //
    // Set the clocking to run directly from the crystal.
    //
    SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_6MHZ);

    //
    // Initialize the OLED display and write status.
    //
    OSRAM96x16x1Init(false);
    OSRAM96x16x1Clear();
	OSRAM96x16x1StringDraw("T1: 0  T2: 0", 12, 1);
    //
    // Enable the peripherals used by this example.
    //
	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    //
    // Enable processor interrupts.
    //
    IntMasterEnable();

    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE, GPIO_PIN_5);


    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,
                        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                         UART_CONFIG_PAR_NONE));

    UARTSend((unsigned char *)"Parameters:\n\r", 13);

    TimerConfigure(TIMER1_BASE, TIMER_CFG_32_BIT_PER);
	TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);
	base1 = SysCtlClockGet()*5;	

	TimerLoadSet(TIMER0_BASE, TIMER_A, base1);
	IntEnable(INT_TIMER0A);
	
	TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
	TimerEnable(TIMER0_BASE, TIMER_A);
    
	base = SysCtlClockGet()/200;

    TimerLoadSet(TIMER1_BASE, TIMER_A, base);
    TimerControlStall(TIMER1_BASE, TIMER_A, true);
    TimerControlTrigger(TIMER1_BASE, TIMER_A, true);


    ADCSequenceConfigure(ADC_BASE, 0, ADC_TRIGGER_TIMER, 0);
    ADCSequenceStepConfigure(ADC_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);
    ADCSequenceEnable(ADC_BASE, 0);
    ADCIntEnable(ADC_BASE, 0);
    //

    TimerEnable(TIMER1_BASE, TIMER_A);
    IntEnable(INT_UART0);
    IntEnable(INT_ADC0);
	while(1)
    {
  		//temp[6]=points;
        if(Flchange==1)
        {
		  TimerLoadSet(TIMER0_BASE, TIMER_A, base1/((*ADCval)-0x29));
		 // TimerLoadSet(TIMER0_BASE, TIMER_A,(unsigned long) base1/(atoi(ADCval)));
		  UARTSend((unsigned char *)"\r", 2);
		  UARTSend((unsigned char *)temp,sizeof(temp));
          Flchange=0;
		  
        }
	   //TimerLoadSet(TIMER0_BASE, TIMER_A,(unsigned long) base1/(atoi(ADCval)));
   	    IntMasterDisable();
   		OSRAM96x16x1StringDraw(HWREGBITW(&g_ulFlags, 0) ? "1" : "0", 36, 1);
       // OSRAM96x16x1StringDraw(temp, 7, 0);
        IntMasterEnable();     
		
 
    }
}
